package com.jinglin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jinglin.component.RedisComponent;
import com.jinglin.entity.constants.Constants;
import com.jinglin.entity.dto.SysSettingDto;
import com.jinglin.entity.dto.TokenUserInfoDto;
import com.jinglin.entity.dto.UserCountInfoDto;
import com.jinglin.entity.enums.PageSize;
import com.jinglin.entity.enums.UserSexEnum;
import com.jinglin.entity.enums.UserStatusEnum;
import com.jinglin.entity.po.*;
import com.jinglin.entity.query.SimplePage;
import com.jinglin.entity.vo.PaginationResultVO;
import com.jinglin.entity.vo.UserInfoVO;
import com.jinglin.exception.BusinessException;

import com.jinglin.mapper.UserInfoMapper;
import com.jinglin.mapper.VideoInfoMapper;
import com.jinglin.service.UserFocusService;
import com.jinglin.service.UserInfoService;
import org.apache.catalina.User;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 用户信息表 服务实现类
 * </p>
 *
 * @author ${author}
 * @since 2025-03-02
 */
@Service
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {

    @Autowired
    private RedisComponent redisComponent;
    @Autowired
    private UserFocusService userFocusService;
    @Autowired
    private UserInfoMapper userInfoMapper;
    @Autowired
    private VideoInfoMapper videoInfoMapper;

    @Override
    public boolean register(String email, String nickName, String registerPassword) {
        LambdaQueryWrapper<UserInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserInfo::getEmail,email);
        // 邮箱不能被人注册
        if (this.getOne(wrapper) != null){
            //如果不为空，停止注册
            throw new BusinessException("邮箱已存在");
        }
        // nickName不能被别人注册
        LambdaQueryWrapper<UserInfo> nameWrapper = new LambdaQueryWrapper<>();
        nameWrapper.eq(UserInfo::getNickName,nickName);
        if (this.getOne(nameWrapper) != null){
            throw new BusinessException("昵称已存在");
        }

        // 注册
        UserInfo userInfo = new UserInfo();
        userInfo.setEmail(email);
        userInfo.setNickName(nickName);
        userInfo.setPassword(DigestUtils.md5DigestAsHex(registerPassword.getBytes(StandardCharsets.UTF_8)));
        userInfo.setJoinTime(new Date());
        userInfo.setStatus(UserStatusEnum.ENABLE.getStatus());
        userInfo.setSex(UserSexEnum.SECRECY.getType());
        userInfo.setTheme(Constants.ONE);
        SysSettingDto sysSettingDto = redisComponent.getSysSettingDto();
        userInfo.setTotalCoinCount(sysSettingDto.getRegisterCoinCount());
        userInfo.setCurrentCoinCount(sysSettingDto.getRegisterCoinCount());
        return this.save(userInfo);
    }

    @Override
    public TokenUserInfoDto login(String email, String password, String ipAddr) {
        LambdaQueryWrapper<UserInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserInfo::getEmail,email);
        UserInfo user = this.getOne(wrapper);
        // 邮箱不能被人注册
        if (user == null){
            //如果不为空，停止注册
            throw new BusinessException("账号不存在");
        }
        if (!user.getPassword().equals(password)){
            throw new BusinessException("账号密码错误");
        }
        if (user.getStatus() == 0){
            throw new BusinessException("账号已被禁用");
        }

        UserInfo userInfo = new UserInfo();
        userInfo.setLastLoginIp(ipAddr);
        userInfo.setLastLoginTime(new Date());
        userInfo.setUserId(user.getUserId());
        this.updateById(userInfo);
        TokenUserInfoDto tokenUserInfoDto = new TokenUserInfoDto();
        BeanUtils.copyProperties(user,tokenUserInfoDto);
        redisComponent.saveTokenInfo(tokenUserInfoDto);
        return tokenUserInfoDto;
    }

    @Override
    public UserInfoVO getUserInfoDetail(String userId) {
        Integer fansCount = userFocusService.getFansCount(userId);
        Integer focusCount = userFocusService.getFocusCount(userId);
        UserInfo userInfo = this.getById(userId);
        userInfo.setFansCount(fansCount);
        userInfo.setFocusCount(focusCount);
        UserInfoVO userInfoVO = new UserInfoVO();
        BeanUtils.copyProperties(userInfo,userInfoVO);
        List<VideoInfo> list = new LambdaQueryChainWrapper<>(videoInfoMapper).eq(VideoInfo::getUserId, userId).select(VideoInfo::getLikeCount).list();
        Integer likeCount = videoInfoMapper.getVideoLikeCountByUserId(userId);
        Integer playCount = videoInfoMapper.getVideoPlayCountByUserId(userId);
        userInfoVO.setLikeCount(likeCount);
        userInfoVO.setPlayCount(playCount);
        return userInfoVO;


    }

    @Override
    public PaginationResultVO loadUser(Integer pageSize, Integer pageNo) {
        // 查出当前用户所属视频的所有弹幕数量。
        int count = this.count();
        pageSize = pageSize == null ? PageSize.SIZE15.getSize() : pageSize;

        SimplePage page = new SimplePage(pageNo, count, pageSize);
        QueryWrapper<UserInfo> wrapper = new QueryWrapper<>();
        wrapper.last("limit "+page.getStart()+","+page.getPageSize());

        List<UserInfo> list = this.list(wrapper);

        PaginationResultVO<UserAction> result = new PaginationResultVO(count, page.getPageSize(), page.getPageNo(), page.getPageTotal(), list);

        return result;
    }

    @Override
    public UserCountInfoDto getUserCountInfo(String userId) {
        UserCountInfoDto userCountInfoDto = new UserCountInfoDto();
        userCountInfoDto.setFansCount(userFocusService.getFansCount(userId));
        userCountInfoDto.setFocusCount(userFocusService.getFocusCount(userId));
        Integer currentCoinCount = new LambdaQueryChainWrapper<>(userInfoMapper).eq(UserInfo::getUserId, userId).select(UserInfo::getCurrentCoinCount).one().getCurrentCoinCount();
        userCountInfoDto.setCurrentCoinCount(currentCoinCount);

        return userCountInfoDto;
    }
}
